/*
	Assignment 5b : Producer and Consumer using Mutex
	Name : Rushikesh Mukund Fanse
	Roll No : 16
	Div : H
*/
#include<cstdio>
#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<cstdlib>
#include<vector>
using namespace std;
pthread_mutex_t mutex;
vector<int> basket;
pthread_cond_t conditional_for_producer,conditional_for_consumer;

int  produce_item()
{
	sleep(2);
	int item=rand()%11;
	cout<<"item produced "<<item<<endl;
	return item;	
}
void consume_item(int item)
{
	sleep(2);
	basket.pop_back();
	cout<<"item consumed "<<item<<endl;
}
void put_into_basket(int item)
{
	basket.push_back(item);
}
int get_from_basket()
{
	return basket.back();
}
void*producer(void*)
{
	int item;
	while(true)
	{	
		pthread_mutex_lock(&mutex);
		while(basket.size()!=0)
		pthread_cond_wait(&conditional_for_producer,&mutex);
		item=produce_item();
		put_into_basket(item);
		pthread_cond_signal(&conditional_for_consumer);
		pthread_mutex_unlock(&mutex);
	}	
}
void*consumer(void*)
{
	int item;
	while(true)
	{
		pthread_mutex_lock(&mutex);
		while(basket.size()==0)
		pthread_cond_wait(&conditional_for_consumer,&mutex);
		item=get_from_basket();
		consume_item(item);
		pthread_cond_signal(&conditional_for_producer);
		pthread_mutex_unlock(&mutex);
	}
}
int main()
{
	pthread_t t1;
	pthread_t t2;
	pthread_mutex_init(&mutex,NULL);
	pthread_cond_init(&conditional_for_producer,NULL);
	pthread_cond_init(&conditional_for_consumer,NULL);
	pthread_create(&t1,NULL,producer,NULL);
	pthread_create(&t2,NULL,consumer,NULL);
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
	pthread_cond_destroy(&conditional_for_producer);
	pthread_cond_destroy(&conditional_for_consumer);	
	return 0;
}
/*
rishi@rishi-PC:~$ ./a.out
item produced 6
item consumed 6
item produced 10
item consumed 10
item produced 6
item consumed 6
item produced 2
item consumed 2
item produced 1
item consumed 1
item produced 4
item consumed 4
item produced 0
item consumed 0

*/
